//============================================================================================
/**
 * @file	touchsel_sublcd.c
 * @brief	下画面タッチ選択専用処理
 * @author	Hiroyuki Nakamura
 * @date	09.04.15
 */
//============================================================================================
#include "common.h"

#include "gflib/touchpanel.h"
#include "system/lib_pack.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "field/field.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_ev_win.h"

#include "../field_poketch.h"

#include "touchsel_sublcd.h"

#include "application/subselect.naix"


//============================================================================================
//	定数定義
//============================================================================================

#define HEAPID_SUBLCD_MENU	( HEAPID_POKETCH_APP )		// ヒープＩＤ

#define	TOUCH_SEL_MAX		( 2 )		// 選択肢最大数

// BMPWIN
#define	BMPWIN_SEL_FRM		( GF_BGL_FRAME0_S )
#define	BMPWIN_SEL_SX		( 30 )
#define	BMPWIN_SEL_SY		( 2 )
#define	BMPWIN_SEL_PAL		( 4 )
// 選択肢１−１
#define	BMPWIN_SEL11_PX		( 1 )
#define	BMPWIN_SEL11_PY		( 12 )
#define	BMPWIN_SEL11_CGX	( 1 )
// 選択肢２−１
#define	BMPWIN_SEL21_PX		( 1 )
#define	BMPWIN_SEL21_PY		( 7 )
#define	BMPWIN_SEL21_CGX	( 1 )
// 選択肢２−２
#define	BMPWIN_SEL22_PX		( 1 )
#define	BMPWIN_SEL22_PY		( 14 )
#define	BMPWIN_SEL22_CGX	( BMPWIN_SEL21_CGX + BMPWIN_SEL_SX * BMPWIN_SEL_SY )

// ボタンデータ
#define	BUTTN_DEF_SX		( 32 )
#define	BUTTN_DEF_SY		( 6 )
#define	BUTTN01_DEF_PX		( 0 )
#define	BUTTN01_DEF_PY		( 10 )
#define	BUTTN02_DEF_PX		( 0 )
#define	BUTTN02_DEF_PY		( 5 )
#define	BUTTN02_SPC_Y		( 1 )
#define	BUTTON_SCRN_GET_POS	( 32 * 6 )						// スクリーン取得位置
#define	BUTTON_SCRN_SIZ		( BUTTN_DEF_SX * BUTTN_DEF_SY )	// スクリーン取得サイズ

// 画面ワーク
typedef struct {
	// フィールドから渡されるもの
	GF_BGL_INI * bgl;
	u16 * sp_trg;
	FIELDSYS_WORK * fsys;
	void * scr_wk;

	TOUCHSEL_PARAM * prm;

	TCB_PTR	tcb;	// 本体のポインタ

	GF_BGL_BMPWIN	win[TOUCH_SEL_MAX];	// BMPWIN

	u16	buttn_scrn[BUTTON_SCRN_SIZ];

	u16	main_seq;
	u16	max;

	int	ret;

}TOUCHSEL_WORK;

// ボタンデータ
typedef struct {
	const BMPWIN_DAT * win;
	const RECT_HIT_TBL * rect;
	u8	button_px;
	u8	button_py;
	u16	button_spc;
}BUTTON_PARAM;


//============================================================================================
//	プロトタイプ宣言
//============================================================================================
static void VramInit(void);
static void BgInit( GF_BGL_INI * bgl );
static void BgExit( GF_BGL_INI * bgl );
static void BmpInit( TOUCHSEL_WORK * wk );
static void BmpExit( TOUCHSEL_WORK * wk );
static void BgGraLoad( TOUCHSEL_WORK * wk );
static void ButtonPut( TOUCHSEL_WORK * wk );
static void ButtonAnmCore( TOUCHSEL_WORK * wk, u8 pal );

static void MainTask( TCB_PTR tcb, void * work );


//============================================================================================
//	グローバル変数
//============================================================================================

// ボタンが１つのときのＢＭＰデータ
static const BMPWIN_DAT BmpWinData01 = {
	BMPWIN_SEL_FRM, BMPWIN_SEL11_PX, BMPWIN_SEL11_PY,
	BMPWIN_SEL_SX, BMPWIN_SEL_SY, BMPWIN_SEL_PAL, BMPWIN_SEL11_CGX
};

// ボタンが２つのときのＢＭＰデータ
static const BMPWIN_DAT BmpWinData02[] =
{
	{
		BMPWIN_SEL_FRM, BMPWIN_SEL21_PX, BMPWIN_SEL21_PY,
		BMPWIN_SEL_SX, BMPWIN_SEL_SY, BMPWIN_SEL_PAL, BMPWIN_SEL21_CGX
	},
	{
		BMPWIN_SEL_FRM, BMPWIN_SEL22_PX, BMPWIN_SEL22_PY,
		BMPWIN_SEL_SX, BMPWIN_SEL_SY, BMPWIN_SEL_PAL, BMPWIN_SEL22_CGX
	},
};

// ボタンが１つのときのタッチデータ
static const RECT_HIT_TBL RectHit01[] =
{
	{ BUTTN01_DEF_PY*8, (BUTTN01_DEF_PY+BUTTN_DEF_SY)*8-1, BUTTN01_DEF_PX*8, (BUTTN01_DEF_PX+BUTTN_DEF_SX)*8-1 },
	{ TP_HIT_END, 0, 0, 0 },
};

// ボタンが２つのときのタッチデータ
static const RECT_HIT_TBL RectHit02[] =
{
	{ BUTTN02_DEF_PY*8, (BUTTN02_DEF_PY+BUTTN_DEF_SY)*8-1, BUTTN02_DEF_PX*8, (BUTTN02_DEF_PX+BUTTN_DEF_SX)*8-1 },
	{ (BUTTN02_DEF_PY+BUTTN_DEF_SY+BUTTN02_SPC_Y)*8, (BUTTN02_DEF_PY+BUTTN_DEF_SY*2+BUTTN02_SPC_Y)*8-1, BUTTN02_DEF_PX*8, (BUTTN02_DEF_PX+BUTTN_DEF_SX)*8-1 },
	{ TP_HIT_END, 0, 0, 0 },
};

// ボタンデータ
static const BUTTON_PARAM ButtonParam[] =
{
	{ &BmpWinData01, RectHit01, BUTTN01_DEF_PX, BUTTN01_DEF_PY, 0 },
	{ BmpWinData02, RectHit02, BUTTN02_DEF_PX, BUTTN02_DEF_PY, BUTTN02_SPC_Y },
};


//--------------------------------------------------------------------------------------------
/**
 * 初期化
 *
 * @param	bgl
 * @param	sub_panel_trg
 * @param	fsys
 * @param	work
 *
 * @return	TCB_PTR
 */
//--------------------------------------------------------------------------------------------
TCB_PTR TouchSelSublcdInit(
			GF_BGL_INI * bgl, u16 * sub_panel_trg, FIELDSYS_WORK * fsys, void * work )
{
	TCB_PTR	tcb;
	TOUCHSEL_WORK * wk;

	// 異様にデカいがポケッチの合計と同じにしておく
	sys_CreateHeap( HEAPID_BASE_APP, HEAPID_SUBLCD_MENU, 0x18000 );

	G2S_BlendNone();

	tcb = PMDS_taskAdd( MainTask, sizeof(TOUCHSEL_WORK), 10, HEAPID_SUBLCD_MENU );
	wk  = TCB_GetWork( tcb );

	wk->bgl    = bgl;
	wk->sp_trg = sub_panel_trg;
	wk->fsys   = fsys;
	wk->scr_wk = work;
	wk->tcb    = tcb;
	wk->prm    = work;
	wk->max    = wk->prm->max;

	wk->prm->ret = TOUCHSEL_SUBLCD_RET_NONE;	// 入力場所初期化
	wk->prm->comm = 0;

	VramInit();
	BgInit( bgl );
	BmpInit( wk );
	BgGraLoad( wk );
	ButtonPut( wk );

	return tcb;
}

//--------------------------------------------------------------------------------------------
/**
 * 終了リクエスト
 *
 * @param	bgl		GF_BGL_INI
 * @param	tcb		TCB_PTR
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void TouchSelSublcdQuitReq( GF_BGL_INI * bgl,  TCB_PTR tcb )
{
	TOUCHSEL_WORK * wk = TCB_GetWork( tcb );

/*
//	MsgExit( wk );
*/
	BmpExit( wk );
	BgExit( wk->bgl );

	// タスク消去
	PMDS_taskDel( tcb );

	sys_DeleteHeap( HEAPID_SUBLCD_MENU );
}

//--------------------------------------------------------------------------------------------
/**
 * 終了待ち
 *
 * @param	bgl		GF_BGL_INI
 *
 * @retval	"TRUE = 終了"
 * @retval	"FALSE = それ以外"
 */
//--------------------------------------------------------------------------------------------
BOOL TouchSelSublcdQuitWait( GF_BGL_INI * bgl )
{
	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * メインタスク
 *
 * @param	tcb		TCB_PTR
 * @param	wk		ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void MainTask( TCB_PTR tcb, void * work )
{
	TOUCHSEL_WORK * wk;
	const BUTTON_PARAM * bp;
	int	ret;

	wk = work;
	bp = &ButtonParam[wk->max-1];

	// ボタンを隠す
/*
	if( wk->main_seq != 3 && wk->prm->comm == TOUCHSEL_SUBLCD_VANISH ){
		wk->main_seq = 2;
	}
*/
	if( wk->main_seq < 2 ){
		if( wk->prm->comm == TOUCHSEL_SUBLCD_VANISH ){
			wk->main_seq = 2;
		}else if( wk->prm->comm == TOUCHSEL_SUBLCD_WAIT ){
			wk->main_seq = 4;
		}
	}

	switch( wk->main_seq ){
	case 0:		// 選択待ち
		wk->ret = GF_TP_RectHitTrg( bp->rect );
		if( wk->ret != RECT_HIT_NONE ){
//			Snd_SePlay( SEQ_SE_DP_SELECT );
			ButtonAnmCore( wk, 1 );
			wk->prm->ret = wk->ret;
			wk->main_seq = 1;
		}
		break;

	case 1:		// 選択中
		ret = GF_TP_RectHitCont( bp->rect );
		wk->prm->ret = TOUCHSEL_SUBLCD_RET_NONE;
		if( ret != wk->ret ){
			ButtonAnmCore( wk, 0 );
			wk->main_seq = 0;
		}
		break;

	case 2:		// ボタンを消す
		GF_BGL_ScrClear( wk->bgl, GF_BGL_FRAME0_S );
		GF_BGL_ScrClear( wk->bgl, GF_BGL_FRAME1_S );
		GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME0_S );
		GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
		wk->main_seq = 3;
		break;

	case 3:
		break;


	case 4:		// ボタンを消してタッチチェックへ
		GF_BGL_ScrClear( wk->bgl, GF_BGL_FRAME0_S );
		GF_BGL_ScrClear( wk->bgl, GF_BGL_FRAME1_S );
		GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME0_S );
		GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
		wk->main_seq = 5;
		break;

	case 5:		// タッチチェック
		if( sys.tp_cont ){
			sys.extra_cont = PAD_BUTTON_A;
		}
		break;
	}
}

//--------------------------------------------------------------------------------------------
/**
 * VRAM初期化
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void VramInit(void)
{
	GX_SetBankForSubBG( GX_VRAM_SUB_BG_32_H );
	GX_SetBankForSubOBJ( GX_VRAM_SUB_OBJ_16_I );
	GXS_SetOBJVRamModeChar( GX_OBJVRAMMODE_CHAR_1D_32K );
}

//--------------------------------------------------------------------------------------------
/**
 * BG初期化
 *
 * @param	bgl		GF_BGL_INI
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BgInit( GF_BGL_INI * bgl )
{
	GXS_SetGraphicsMode( GX_BGMODE_0 );

	{
		GF_BGL_BGCNT_HEADER head = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x7800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			0, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( bgl, GF_BGL_FRAME0_S, &head, GF_BGL_MODE_TEXT );
		GF_BGL_ClearCharSet( GF_BGL_FRAME0_S, 32, 0, HEAPID_SUBLCD_MENU );
		GF_BGL_ScrClear( bgl, GF_BGL_FRAME0_S );
	}
	{
		GF_BGL_BGCNT_HEADER head = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x7000, GX_BG_CHARBASE_0x04000, GX_BG_EXTPLTT_01,
			1, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( bgl, GF_BGL_FRAME1_S, &head, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( bgl, GF_BGL_FRAME1_S );
	}
	{
		GF_BGL_BGCNT_HEADER head = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x6800, GX_BG_CHARBASE_0x04000, GX_BG_EXTPLTT_01,
			2, 0, 0, FALSE

		};
		GF_BGL_BGControlSet( bgl, GF_BGL_FRAME2_S, &head, GF_BGL_MODE_TEXT );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * BG解放
 *
 * @param	bgl		GF_BGL_INI
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BgExit( GF_BGL_INI * bgl )
{
	GF_BGL_BGControlExit( bgl, GF_BGL_FRAME2_S );
	GF_BGL_BGControlExit( bgl, GF_BGL_FRAME1_S );
	GF_BGL_BGControlExit( bgl, GF_BGL_FRAME0_S );
}

//--------------------------------------------------------------------------------------------
/**
 * BMP初期化
 *
 * @param	wk		画面ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BmpInit( TOUCHSEL_WORK * wk )
{
	const BUTTON_PARAM * bp;
	u32	i;

	bp = &ButtonParam[wk->max-1];

	for( i=0; i<wk->max; i++ ){
		GF_BGL_BmpWinAddEx( wk->bgl, &wk->win[i], &bp->win[i] );
		GF_BGL_BmpWinDataFill( &wk->win[i], 0 );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * BMP解放
 *
 * @param	wk		ダウジング画面ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BmpExit( TOUCHSEL_WORK * wk )
{
	u32	i;

	for( i=0; i<wk->max; i++ ){
		GF_BGL_BmpWinDel( &wk->win[i] );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * BGグラフィックロード
 *
 * @param	wk		画面ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BgGraLoad( TOUCHSEL_WORK * wk )
{
	// ファイルハンドルオープン
	ARCHANDLE * ah = ArchiveDataHandleOpen( ARC_SUBSELECT_GRA, HEAPID_SUBLCD_MENU );

    ArcUtil_HDL_PalSet(
		ah, NARC_subselect_bmpmenu_nclr, PALTYPE_SUB_BG, 0, 32*5, HEAPID_SUBLCD_MENU );

	ArcUtil_HDL_BgCharSet(
		ah, NARC_subselect_bmpmenu_bg_ncgr,
		wk->bgl, GF_BGL_FRAME1_S, 0, 0, 0, HEAPID_SUBLCD_MENU );

	ArcUtil_HDL_ScrnSet(
		ah, NARC_subselect_bmpmenu_back_nscr,
		wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_SUBLCD_MENU );

	{	// ボタンスクリーン取得
		NNSG2dScreenData * scrn;
		void * buf;
		u16 * dat;

		buf = ArcUtil_HDL_ScrnDataGet(
				ah, NARC_subselect_bmpmenu_yn_nscr, FALSE, &scrn, HEAPID_SUBLCD_MENU  );
		dat = (u16 *)scrn->rawData;

		MI_CpuCopy16( &dat[BUTTON_SCRN_GET_POS], &wk->buttn_scrn, BUTTON_SCRN_SIZ*2 );

		sys_FreeMemoryEz( buf );
	}

	// ファイルハンドルクローズ
	ArchiveDataHandleClose( ah );
}

//--------------------------------------------------------------------------------------------
/**
 * ボタン配置
 *
 * @param	wk		画面ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void ButtonPut( TOUCHSEL_WORK * wk )
{
	const BUTTON_PARAM * bp;
	MSGDATA_MANAGER * mman;
	STRBUF * str;
	u16	px;
	u16	i;

	// タッチフォント読み込み
	FontProc_LoadFont( FONT_TOUCH, HEAPID_SUBLCD_MENU );

	mman = MSGMAN_Create( MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_ev_win_dat, HEAPID_SUBLCD_MENU );

	bp = &ButtonParam[wk->max-1];

	for( i=0; i<wk->max; i++ ){
		GF_BGL_ScrWrite(
			wk->bgl, GF_BGL_FRAME1_S, wk->buttn_scrn,
			bp->button_px,
			bp->button_py + ( BUTTN_DEF_SY + bp->button_spc ) * i,
			BUTTN_DEF_SX, BUTTN_DEF_SY );

		str = MSGMAN_AllocString( mman, wk->prm->tbl[i] );
		px  = GF_BGL_BmpWinGet_SizeX( &wk->win[i] ) * 8 / 2;
		px -= ( FontProc_GetPrintStrWidth( FONT_TOUCH, str, 0 ) / 2 );
		GF_STR_PrintColor(
			&wk->win[i], FONT_TOUCH, str, px, 0,
			MSG_NO_PUT, GF_PRINTCOLOR_MAKE(2,1,0), NULL );
		GF_BGL_BmpWinCgxOn( &wk->win[i] );
		GF_BGL_BmpWinOnVReq( &wk->win[i] );
		STRBUF_Delete( str );
	}

	MSGMAN_Delete( mman );

	FontProc_UnloadFont( FONT_TOUCH );

	GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
}

//--------------------------------------------------------------------------------------------
/**
 * ボタン切り替え
 *
 * @param	wk		画面ワーク
 * @param	pal		パレット
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void ButtonAnmCore( TOUCHSEL_WORK * wk, u8 pal )
{
	const BUTTON_PARAM * bp = &ButtonParam[wk->max-1];

	GF_BGL_ScrPalChange(
		wk->bgl, GF_BGL_FRAME1_S,
		bp->button_px, bp->button_py + ( BUTTN_DEF_SY + bp->button_spc ) * wk->ret,
		BUTTN_DEF_SX, BUTTN_DEF_SY, pal );

	GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
}